這裡將利用教程所提供的"Treasure Hunter Game"來直接學習PixiJS中的語法。"Treasure Hunter Game"的程式碼 ---> Click Here !
系統提示:「A man can succeed at almost anything for which he has unlimited enthusiasm.」,PixiJS青銅玩家完成自定義function階段任務,獲得一把看起來還不錯的劍,從這裡開始將要自行探索未知地圖。
這是一般情況下,當角色移動時,畫面並不會跟著動,這種作法僅限於地圖很小的情況下適用。
但是若是在大地圖的情況下,我會希望他能永遠置中,如google doodle的冠軍島任務一樣。
這裡將會利用PIXI, TypeScript: Character Keyboard Movements + Screen Follow此網站的圖片作為練習,但程式碼僅作為參考,主要是看他的想法(畢竟他是用typeScript,我不會QQ)。
***
先把基本設定給設置完成。(順便複習一下之前的內容)
完成的codepen參考。
let Application = PIXI.Application,
Container = PIXI.Container,
loader = PIXI.loader,
resources = PIXI.loader.resources,
Graphics = PIXI.Graphics,
TextureCache = PIXI.utils.TextureCache,
Sprite = PIXI.Sprite,
Text = PIXI.Text,
TextStyle = PIXI.TextStyle;
let state, explorer, treasure, blobs, chimes, exit, player, dungeon,
door, healthBar, message, gameScene, gameOverScene, enemies, id;
建立一個寬高各為512px的畫布。
let app = new Application({
width: 512,
height: 512,
antialiasing: true,
transparent: false,
resolution: 1
}
);
document.body.appendChild(app.view);
這裡是把圖片用網址的方式載入,當然也可以放到資料夾中,利用檔案路徑的方式。
loader
.add("map","https://i.imgur.com/Dhw1CcR.png")
.add("explorer","https://i.imgur.com/FEuTd7c.png")
.load(setUp);
大方向分成幾個部份:
function setUp(){
//1. 遊戲場景設置
gameScene = new Container();
app.stage.addChild(gameScene);
//2. 角色Sprites建立
map = new Sprite(resources["map"].texture);
gameScene.addChild(map);
explorer = new Sprite(resources["explorer"].texture);
gameScene.addChild(explorer);
explorer.vx = 0;
explorer.vy = 0;
//3. 鍵盤設置
let left = keyboard(37),
up = keyboard(38),
right = keyboard(39),
down = keyboard(40);
left.press = function() {
explorer.vx = -5;
explorer.vy = 0;
};
left.release = function() {
if (!right.isDown && explorer.vy === 0) {
explorer.vx = 0;
}
};
up.press = function() {
explorer.vy = -5;
explorer.vx = 0;
};
up.release = function() {
if (!down.isDown && explorer.vx === 0) {
explorer.vy = 0;
}
};
right.press = function() {
explorer.vx = 5;
explorer.vy = 0;
};
right.release = function() {
if (!left.isDown && explorer.vy === 0) {
explorer.vx = 0;
}
};
down.press = function() {
explorer.vy = 5;
explorer.vx = 0;
};
down.release = function() {
if (!up.isDown && explorer.vx === 0) {
explorer.vy = 0;
}
};
//4.遊戲狀態設為「play()」
state = play;
//5. 執行遊戲迴圈
app.ticker.add((delta) => gameLoop(delta));
}
function gameLoop(delta){
state(delta);
}
放置遊戲邏輯的地方,大方向分為以下部份:
function play(delta){
//1. 更新玩家的位置
explorer.x += explorer.vx;
explorer.y += explorer.vy;
//2. 範圍限制的設置
contain(explorer, {x: 28, y: 10, width: 488, height: 480});
}
用來限制角色活動範圍。
function contain(sprite, container) {
let collision = undefined;
if (sprite.x < container.x) {
sprite.x = container.x;
collision = "left";
}
if (sprite.y < container.y) {
sprite.y = container.y;
collision = "top";
}
if (sprite.x + sprite.width > container.width) {
sprite.x = container.width - sprite.width;
collision = "right";
}
if (sprite.y + sprite.height > container.height) {
sprite.y = container.height - sprite.height;
collision = "bottom";
}
return collision;
}
function keyboard(keyCode) {
var key = {};
key.code = keyCode;
key.isDown = false;
key.isUp = true;
key.press = undefined;
key.release = undefined;
key.downHandler = function(event) {
if (event.keyCode === key.code) {
if (key.isUp && key.press) key.press();
key.isDown = true;
key.isUp = false;
}
event.preventDefault();
};
key.upHandler = function(event) {
if (event.keyCode === key.code) {
if (key.isDown && key.release) key.release();
key.isDown = false;
key.isUp = true;
}
event.preventDefault();
};
window.addEventListener(
"keydown", key.downHandler.bind(key), false
);
window.addEventListener(
"keyup", key.upHandler.bind(key), false
);
return key;
}
先想想看他需要更改什麼?首先,我們希望角色可以置中於畫布之上,除了當角色移動到地圖的邊邊(這裡的地圖指的是「底圖」,以此處為例,即如下那張綠色的地圖)
基本上地圖比我們的畫布(畫布即顯示在網頁之上的可視範圍,等等說明會用「screen」取代)還要大,所以我們使地圖位置可以移動,讓他的位置以角色做相對的移動。
***
第一件事情就是先將角色的錨點(anchor)從預設在左上角,改到中心(也就是該explorer的原點改到中心):
explorer.anchor.set(0.5,0.5);
接著,來看看地圖如何與角色相對的改變位置,下圖為初始狀態:
我們把地圖移動到位置(-elorer.x,-explorer.y):
為了讓角色explorer可以置中於screen,所以地圖又挪動了半個screen的寬以及高:
至於程式碼如下:
explorer.anchor.set(0.5,0.5);
explorer.x = app.screen.width * 0.5;
explorer.y = app.screen.height * 0.5;
screenCenterX = app.screen.width * 0.5;
screenCenterY = app.screen.height * 0.5;
newMapPosX = -explorer.x + screenCenterX;
newMapPosY = -explorer.y + screenCenterY;
map.x = newMapPosX;
map.y = newMapPosY;
附上codepen的示範,不過目前還有些問題找不到,決定明天處理!
又是一個寫了5個小時的一篇,然而寫出來的東西還是有bug,甚至不知道問題出在哪邊,但是等等還要趕打工,回來十點多了大概也沒時間改,所以...就留到明天來處理吧(目前猜測可能是改了explorer的anchor、限制範圍沒處理好,就是當screen的邊界撞到map的邊界處理)